﻿@using Grand.Domain.Blogs
@model SearchBoxModel
@inject BlogSettings blogSettings
@inject IWorkContextAccessor workContextAccessor
@{
    var lang = workContextAccessor.WorkContext.WorkingLanguage.LanguageCulture;
}
<ul class="search-item">
    <li>
        <template id="searchBoxContainer">
            <validation-observer v-slot="{ handleSubmit }">
                <form asp-route="ProductSearch" method="get" id="small-search-box-form" ref="searchForm" v-on:submit.prevent="handleSubmit(searchbox.formSubmit)" class="searchBox w-100">
                    <validation-provider tag="div" rules="required|min:@(Model.SearchTermMinimumLength)" name="q" v-slot="{ errors, classes }">
                        <input type="hidden" asp-for="Box" value="true"/>
                        <label for="small-searchterms" class="sr-only">@Loc["Search.SearchBox.Tooltip"]</label>
                        <div class="input-group flex-row">
                            <input minlength="@(Model.SearchTermMinimumLength)" maxlength="20"
                                   data-val-required="@string.Format(Loc["search.searchtermminimumlengthisncharacters"], Model.SearchTermMinimumLength)"
                                   data-val-min="@string.Format(Loc["search.searchtermminimumlengthisncharacters"], Model.SearchTermMinimumLength)"
                                   @if (Model.AutoCompleteEnabled)
                                   {
                                       <text> @@input="searchbox.autocompleteVue()" </text>
                                   }
                                   v-model="searchbox.text" type="search" name="q" ref="searchBoxInput" class="form-control search-box-text" id="small-searchterms" :placeholder="searchbox.placeholder">

                            @if (Model.AvailableCategories.Any())
                            {
                                <select asp-for="SearchCategoryId" asp-items="Model.AvailableCategories" class="search-box-select custom-select input-group-addon"></select>
                            }
                            @await Component.InvokeAsync("Widget", new { widgetZone = "searchbox_before_search_button" })

                            <div class="input-group-append">
                                @if (Model.VoiceNavigatioEnabled)
                                {
                                    <button id="voiceSearchButton"
                                            v-if="searchbox.allowed"
                                            @@touchstart="searchbox.recording = true"
                                            @@touchcancel="searchbox.recording = false; $root.$emit('bv::hide::tooltip')"
                                            @@touchend="searchbox.recording = false; $root.$emit('bv::hide::tooltip')"
                                            @@mousedown="searchbox.recording = true"
                                            @@mouseup="searchbox.recording = false"
                                            @@mouseleave="searchbox.recording = false"
                                            v-b-tooltip.hover.bottom :title="searchbox.micMessage" ref="micBtn" type="button" v-bind:class="[{ focus: searchbox.recording }, 'btn btn-outline-secondary search-button btn-mic']">
                                        <template v-if="searchbox.recording">
                                            <span class="icons icon-microphone"></span>
                                        </template>
                                        <template v-else>
                                            <span class="icons icon-microphone"></span>
                                        </template>
                                    </button>
                                }
                                <button type="submit" class="btn btn-outline-secondary search-box-button search-button float-sm-right d-inline-flex align-items-center">
                                    <span class="sr-only">@Loc["Search.SearchBox.Tooltip"]</span>
                                    <span class="icons icon-magnifier"></span>
                                </button>
                            </div>
                        </div>
                    </validation-provider>
                    <template v-if="searchbox.searchitems !== null">
                        <div id="adv_search" class="advanced-search-results" onclick="StopPropagation(event)">
                            <div class="col-12">
                                <div class="form-row">
                                    <div class="col-md-6 col-12">
                                        <h5 class="title">@Loc["search.category"]</h5>
                                        <div v-if="searchbox.searchcategories.length">
                                            <ul class="list px-0">
                                                <li v-for="item in searchbox.searchcategories">
                                                    <h6 class="mb-0">
                                                        <a :href="item.Url">{{item.Label}}</a>
                                                    </h6>
                                                    <p v-if="item.Desc">{{item.Desc}}</p>
                                                </li>
                                            </ul>
                                        </div>
                                        <ul v-else class="px-0 mb-1">
                                            <li class="alert alert-info">@Loc["search.noresultstextcategory"]</li>
                                        </ul>
                                        <h5 class="title">@Loc["search.brand"]</h5>
                                        <div v-if="searchbox.searchbrands.length">
                                            <ul class="list px-0">
                                                <li v-for="item in searchbox.searchbrands">
                                                    <h6 class="mb-0">
                                                        <a :href="item.Url">{{item.Label}}</a>
                                                    </h6>
                                                    <p v-if="item.Desc">{{item.Desc}}</p>
                                                </li>
                                            </ul>
                                        </div>
                                        <ul v-else class="px-0 mb-1">
                                            <li class="alert alert-info">@Loc["search.noresultstextbrand"]</li>
                                        </ul>
                                        @if (blogSettings.ShowBlogPostsInSearchAutoComplete)
                                        {
                                            <h5 class="title">@Loc["search.blog"]</h5>
                                            <div v-if="searchbox.searchblog.length">
                                                <ul class="list px-0">
                                                    <li v-for="item in searchbox.searchblog">
                                                        <h6 class="mb-0">
                                                            <a :href="item.Url">{{item.Label}}</a>
                                                        </h6>
                                                        <p v-if="item.Desc">{{item.Desc}}</p>
                                                    </li>
                                                </ul>
                                            </div>
                                            <ul v-else class="px-0 mb-1">
                                                <li class="alert alert-info">@Loc["search.noresultstextblog"]</li>
                                            </ul>
                                        }
                                    </div>
                                    <div class="col-md-6 col-12 products">
                                        <h5 class="title">@Loc["search.products"]</h5>
                                        <div v-if="searchbox.searchproducts.length">
                                            <ul class="list px-0">
                                                <li class="media" v-for="item in searchbox.searchproducts">
                                                    <div class="media-aside" v-if="item.PictureUrl">
                                                        <img class="img-fluid" alt="placeholder" :src="item.PictureUrl"/>
                                                    </div>
                                                    <div class="media-body">
                                                        <h6 class="mb-0">
                                                            <a :href="item.Url">{{item.Label}}</a>
                                                        </h6>
                                                        <b-form-rating class="p-0" variant="warning" no-border size="sm" show-value precision="2" readonly inline :value="item.Rating / 20"></b-form-rating>
                                                        <div v-if="item.Price" class="price">{{item.Price}}</div>
                                                        <p v-html="item.Desc" class="mt-1 mb-0"></p>
                                                    </div>
                                                </li>
                                            </ul>
                                        </div>
                                        <ul v-else class="px-0 mb-1">
                                            <li class="alert alert-info">@Loc["search.noresultstext"]</li>
                                        </ul>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </template>
                    @await Component.InvokeAsync("Widget", new { widgetZone = "searchbox" })
                </form>
            </validation-observer>
        </template>
        <script asp-location="Footer" asp-order="300">
    var searchBox = Vue.extend({
        data: () => ({
            recording: false,
            recognition: null,
            searchitems: null,
            focus: false,
            text: "",
            lang: '@lang',
            placeholder: "@Loc["Search.SearchBox.Tooltip"]",
            micMessage: "@Loc["search.voice.holdtospeak"]",
            searchcategories: null,
            searchbrands: null,
            searchblog: null,
            searchproducts: null,
            allowed: true,
        }),
        methods: {
            formSubmit() {
                vm.$refs.searchForm.submit();
            },
            startRecording() {
                this.recognition.start();
            },
            stopRecording() {
                this.recognition.stop();
            },
            allowCheck() {
                var checkPermission = navigator.permissions
                if (checkPermission) {
                    navigator.permissions.query(
                        { name: 'microphone' }
                    ).then(function (permissionStatus) {
                        if (permissionStatus.state == "denied") {
                            searchbox.allowed = false;
                        } else {
                            searchbox.allowed = true;
                        }
                        permissionStatus.onchange = function () {
                            if (this.state == "denied") {
                                searchbox.allowed = false;
                            } else {
                                searchbox.allowed = true;
                            }
                        }
                    })
                }
            },
            autocompleteVue() {                
                const minLength = vm.$refs.searchBoxInput.getAttribute('minlength');
                const length = vm.$refs.searchBoxInput.value.length;
                var delayTimer;
                function getCategories(item) {
                    if (item.SearchType == 'Category') {
                        return item
                    }
                }
                function getBrands(item) {
                    if (item.SearchType == 'Brand') {
                        return item
                    }
                }
                function getBlog(item) {
                    if (item.SearchType == 'Blog') {
                        return item
                    }
                }
                function getProducts(item) {
                    if (item.SearchType == 'Product') {
                        return item
                    }
                }
                clearTimeout(delayTimer);
                delayTimer = setTimeout(function () {
                    var value = searchbox.text;
                    var category = '';
                    if (document.getElementById("SearchCategoryId")) {
                        category = document.getElementById("SearchCategoryId").value;
                    }
                    if (length >= minLength) {
                        axios({
                            url: '/catalog/searchtermautocomplete',
                            method: 'get',
                            params: {
                                term: value,
                                categoryId: category
                            }
                        }).then(function (response) {
                            if (response.data) {
                                searchbox.searchitems = response.data;
                                var categories = response.data.map(getCategories).filter(function (element) {
                                    return element !== undefined;
                                });
                                var brands = response.data.map(getBrands).filter(function (element) {
                                    return element !== undefined;
                                });
                                var blog = response.data.map(getBlog).filter(function (element) {
                                    return element !== undefined;
                                });
                                var products = response.data.map(getProducts).filter(function (element) {
                                    return element !== undefined;
                                });
                                searchbox.searchcategories = categories;
                                searchbox.searchbrands = brands;
                                searchbox.searchblog = blog;
                                searchbox.searchproducts = products;
                            }
                        })
                    }
                }, 600);
            }
        },
        created() {
            this.allowCheck();
        },
        watch: {
            text: function () {
                const searchBoxInput = vm.$refs.searchBoxInput;
                this.autocompleteVue(searchBoxInput);
                if (this.text == '') {
                    searchbox.searchitems = null;
                }
            },
            recording: function () {
                const speech = window.SpeechRecognition || window.webkitSpeechRecognition;
                if (speech) {
                    if (this.recording) {

                        this.$bvToast.toast('@Loc["search.voice.annotation"]', {
                            title: '@Loc["search.voice.placeholder"]',
                            variant: 'info',
                            autoHideDelay: 3000,
                            solid: true
                        })

                        this.recognition = new speech();
                        this.recognition.continuous = true;
                        this.recognition.lang = searchbox.lang;
                        const searchForm = vm.$refs.searchForm;
                        const searchBoxInput = vm.$refs.searchBoxInput;
                        searchBoxInput.focus();
                        this.startRecording();
                        this.placeholder = '@Loc["search.voice.placeholder"]';
                        this.micMessage = '@Loc["search.voice.placeholder"]';
                        this.recognition.addEventListener("result", resultOfSpeechRecognition);
                        function resultOfSpeechRecognition(event) {
                            const current = event.resultIndex;
                            const transcript = event.results[current][0].transcript;
                            if (transcript.toLowerCase().trim() === "@Loc["search.voice.stop"]") {
                                searchbox.stopRecording();
                            }
                            else if (!searchBoxInput.value && searchbox.recording) {
                                searchbox.text = transcript;
                            }
                            else {
                                if (transcript.toLowerCase().trim() === '@Loc["search.voice.go"]') {
                                    searchbox.stopRecording();
                                    searchForm.submit();
                                }
                                else if (transcript.toLowerCase().trim() === '@Loc["search.voice.reset"]') {
                                    searchbox.text = "";
                                }
                                else if (searchbox.recording) {
                                    searchbox.text = transcript;
                                }
                            }
                        }
                    } else {
                        this.stopRecording();
                        this.placeholder = '@Loc["Search.SearchBox.Tooltip"]';
                        this.micMessage = '@Loc["search.voice.holdtospeak"]'
                    }
                } else {
                    this.allowed = false;
                }
            }
        }
    });
    var searchbox = new searchBox().$mount('#small-search-box-form')
        </script>
    </li>
</ul>